//
//  MKUICustomTabBarController.m
//  MKUI
//
//  Created by 苏尚进 on 2023/8/2.
//  Copyright © 2023 moon. All rights reserved.
//

#import "MKUICustomTabBarController.h"
#import "CGGeometry+MKUI.h"
#import "UIView+MKUI.h"
#import "UIColor+MKUI.h"
#import "NSArray+MKUI.h"

//可以自定义safeAreaInsets的容器视图
@interface _MKUICustomTabBarContainerView : UIView
@property(nonatomic,assign) UIEdgeInsets mk_customSafeAreaInsets;
@property(nonatomic,assign) BOOL mk_useCustomSafeAreaInsets;
@end
@implementation _MKUICustomTabBarContainerView
#ifdef DEBUG
- (void)dealloc{
    
}
#endif
- (void)setMk_customSafeAreaInsets:(UIEdgeInsets)mk_customSafeAreaInsets{
    if(UIEdgeInsetsEqualToEdgeInsets(_mk_customSafeAreaInsets, mk_customSafeAreaInsets))return;
    _mk_customSafeAreaInsets = mk_customSafeAreaInsets;
    if (@available(iOS 11.0, *)) {
        [self safeAreaInsetsDidChange];
    }
}
- (UIEdgeInsets)safeAreaInsets{
    if(self.mk_useCustomSafeAreaInsets){
        return self.mk_customSafeAreaInsets;
    }else{
        return [super safeAreaInsets];
    }
}
@end

@interface MKUICustomTabBarController (){
}
@property(nonatomic,strong) UIView *viewContainer;
@property(nonatomic,strong) _MKUICustomTabBarContainerView *tabBarContainer;
@property(nonatomic,strong) MKUICustomTabBar *tabBar;
@property(nonatomic,assign) BOOL tabBarHidden;//tarBar是否隐藏
@end

@implementation MKUICustomTabBarController
#ifdef DEBUG
- (void)dealloc{
    
}
#endif
- (id)init{
    if(self=[super init]){
    }
    return self;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.viewContainer = [[UIView alloc] init];
    [self.view addSubview:self.viewContainer];
    //
    self.tabBarContainer = [[_MKUICustomTabBarContainerView alloc] init];
    self.tabBarContainer.mk_useCustomSafeAreaInsets = YES;
    [self.tabBarContainer addSubview:self.tabBar];
    [self.view addSubview:self.tabBarContainer];
    [self _update_additionalSafeAreaInsets];
}
- (void)_update_additionalSafeAreaInsets{
    BOOL translucent = self.tabBar.translucent;
    UIEdgeInsets additionalSafeAreaInsets = UIEdgeInsetsZero;
    BOOL tarBarHidden = self.tabBarHidden;
    if(translucent && !tarBarHidden){
        CGFloat tabBarItemHeight = self.tabBar.itemHeight;
        additionalSafeAreaInsets.bottom = tabBarItemHeight;
    }
    if (@available(iOS 11.0, *)) {
        self.additionalSafeAreaInsets = additionalSafeAreaInsets;
    }
}
- (void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    [self _update_additionalSafeAreaInsets];
    CGRect bounds = self.view.bounds;
    //
    BOOL translucent = self.tabBar.translucent;
    BOOL tarBarHidden = self.tabBarHidden;
    CGFloat tabBarItemHeight = self.tabBar.itemHeight;
    
    UIEdgeInsets additionalSafeAreaInsets = UIEdgeInsetsZero;
    if (@available(iOS 11.0, *)) {
        additionalSafeAreaInsets = self.additionalSafeAreaInsets;
    }
    
    UIEdgeInsets safeAreaInsets = UIEdgeInsetsZero;
    if (@available(iOS 11.0, *)) {
        safeAreaInsets = self.view.safeAreaInsets;
    }
    
    CGRect viewContainerFrame = bounds;
    if(!translucent && !tarBarHidden){//不透明
        viewContainerFrame.size.height -= safeAreaInsets.bottom+tabBarItemHeight;
    }
    self.viewContainer.frame = viewContainerFrame;
    
    UIEdgeInsets tabBarContainerSafeAareaInsets = safeAreaInsets;
    tabBarContainerSafeAareaInsets.top = 0;
    tabBarContainerSafeAareaInsets.bottom = safeAreaInsets.bottom-additionalSafeAreaInsets.bottom;
    self.tabBarContainer.mk_customSafeAreaInsets = tabBarContainerSafeAareaInsets;
    
    CGRect f1 = bounds;
    f1.size.height = tabBarItemHeight;
    f1.size.height += safeAreaInsets.bottom-additionalSafeAreaInsets.bottom;
    MKCGRectAlignMaxYToRect(&f1, bounds);
    self.tabBarContainer.mk_frameSafety = f1;
    self.tabBar.mk_frameSafety = self.tabBarContainer.bounds;
    [self.tabBar layoutIfNeeded];
    
    UIViewController *selectedViewController = self.selectedViewController;
    if(selectedViewController){
        selectedViewController.view.frame = self.viewContainer.bounds;
    }
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    if(self.selectedIndex==NSNotFound){//默认选中第一个
        self.selectedIndex = 0;
    }
    [self.selectedViewController beginAppearanceTransition:YES animated:animated];
}
- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self.selectedViewController endAppearanceTransition];
}
- (void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.selectedViewController beginAppearanceTransition:NO animated:animated];
}
- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.selectedViewController endAppearanceTransition];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
    return self.selectedViewController.preferredStatusBarStyle;
}
- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation {
    return self.selectedViewController.preferredStatusBarUpdateAnimation;
}
- (void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers{
    [self setViewControllers:viewControllers animated:NO];
}
- (void)setViewControllers:(NSArray<__kindof UIViewController *> *)viewControllers animated:(BOOL)animated{
    if(_viewControllers==viewControllers||[_viewControllers isEqualToArray:viewControllers])return;
    NSArray<UIViewController *> *removeViewControllers = [self.viewControllers mk_removeObjectsInArray:viewControllers];
    for(UIViewController *vc in removeViewControllers){
        [vc willMoveToParentViewController:nil];
        [vc removeFromParentViewController];
        [vc didMoveToParentViewController:nil];
    }
    NSArray<UIViewController *> *newViewControllers = [viewControllers mk_removeObjectsInArray:self.viewControllers];
    for(UIViewController *vc in newViewControllers){
        [self addChildViewController:vc];
        [vc didMoveToParentViewController:self];
    }
    _viewControllers = viewControllers;
    
    if(self.selectedViewController && self.selectedIndex==NSNotFound){
        self.selectedIndex = 0;
    }
    [self __reloadTabBarDataWithAnimated:animated];
}
- (void)setSelectedIndex:(NSUInteger)selectedIndex{
    if(self.selectedIndex==selectedIndex)return;
    UIViewController *vc = selectedIndex>=0&&selectedIndex<self.viewControllers.count?self.viewControllers[selectedIndex]:nil;
    self.selectedViewController = vc;
}
- (NSUInteger)selectedIndex{
    if(!self.selectedViewController)return NSNotFound;
    return [self.viewControllers indexOfObject:self.selectedViewController];
}
- (void)setSelectedViewController:(__kindof UIViewController *)selectedViewController{
    if(_selectedViewController==selectedViewController)return;
    if(selectedViewController&&[self.viewControllers indexOfObject:selectedViewController]==NSNotFound)return;
    if(_selectedViewController){
        [_selectedViewController beginAppearanceTransition:NO animated:NO];
        [_selectedViewController.view removeFromSuperview];
        [_selectedViewController endAppearanceTransition];
    }
    _selectedViewController = selectedViewController;
    if(_selectedViewController){
        [_selectedViewController beginAppearanceTransition:YES animated:NO];
        _selectedViewController.view.frame = self.viewContainer.bounds;
        [self.viewContainer addSubview:_selectedViewController.view];
        [_selectedViewController endAppearanceTransition];
    }
    [self.tabBar setSelectedIndex:self.selectedIndex animated:YES];
    [self setNeedsStatusBarAppearanceUpdate];
    if (@available(iOS 16.0, *)) {
        [self setNeedsUpdateOfSupportedInterfaceOrientations];
    }
}
- (MKUICustomTabBar *)tabBar{
    if(_tabBar)return _tabBar;
    Class customTabBarClass = [self tabBarClass];
    if(!customTabBarClass) customTabBarClass = MKUICustomTabBar.class;
    MKUICustomTabBar *view = [[customTabBarClass alloc] init];
    view.delegate = self;
    @MK_WEAKIFY(self);
    view.whenPropertyChange = ^(MKUICustomTabBar * _Nonnull customTabBar) {
        @MK_NORMALIZE(self);
        [self.view setNeedsLayout];
    };
    _tabBar = view;
    return _tabBar;
}
- (void)setTabBarClass:(Class)tabBarClass{
    if(_tabBarClass==tabBarClass)return;
    if(!tabBarClass){
        tabBarClass = MKUICustomTabBar.class;
    }
    _tabBarClass = tabBarClass;
    if(!_tabBar)return;
    [_tabBar removeFromSuperview];
    _tabBar = nil;
    [self.tabBarContainer addSubview:self.tabBar];
    [self.view setNeedsLayout];
    [self __reloadTabBarDataWithAnimated:NO];
}
- (void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated{
    if(self.tabBarHidden == hidden)return;
    if(animated){
        self.tabBarContainer.hidden = NO;
        CGAffineTransform m = CGAffineTransformIdentity;
        CGFloat tabbarHeight = self.tabBarContainer.bounds.size.height;
        CGAffineTransform m_hidden = CGAffineTransformMakeTranslation(0, tabbarHeight);
        if(hidden){
            m = m_hidden;
        }else{
            self.tabBarContainer.transform = m_hidden;
        }
        self.tabBarHidden = hidden;
        [UIView animateWithDuration:0.25 animations:^{
            self.tabBarContainer.transform = m;
            [self.view setNeedsLayout];
            [self.view layoutIfNeeded];
        } completion:^(BOOL finished) {
            self.tabBarHidden = hidden;
            self.tabBarContainer.hidden = hidden;
            self.tabBarContainer.transform = CGAffineTransformIdentity;
            [self.view setNeedsLayout];
            [self.view layoutIfNeeded];
        }];
    }else{
        self.tabBarHidden = hidden;
        self.tabBarContainer.hidden = hidden;
        [self.view setNeedsLayout];
        [self.view layoutIfNeeded];
    }
}
- (void)__reloadTabBarDataWithAnimated:(BOOL)animated{
    self.tabBar.items = self.viewControllers;
    self.tabBar.selectedIndex = self.selectedIndex;
    [self.tabBar reloadDataWithAnimated:animated];
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations{
    if([self.delegate respondsToSelector:@selector(customTabBarControllerSupportedInterfaceOrientations:)]){
        return [self.delegate customTabBarControllerSupportedInterfaceOrientations:self];
    }
    if(self.selectedViewController){
        return self.selectedViewController.supportedInterfaceOrientations;
    }
    return [super supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
    if([self.delegate respondsToSelector:@selector(customTabBarControllerPreferredInterfaceOrientationForPresentation:)]){
        return [self.delegate customTabBarControllerPreferredInterfaceOrientationForPresentation:self];
    }
    if(self.selectedViewController){
        return self.selectedViewController.preferredInterfaceOrientationForPresentation;
    }
    return [super preferredInterfaceOrientationForPresentation];
}
#pragma mark - delegate:MKUItemFlowCollectionViewDelegate
- (void)itemFlowCollectionView:(MKUItemFlowCollectionView *)view didSelectIndex:(NSInteger)selectedIndex{
    UIViewController *viewController = self.viewControllers[selectedIndex];
    if(self.delegate&&[self.delegate respondsToSelector:@selector(customTabBarController:shouldSelectViewController:)]){
        if(![self.delegate customTabBarController:self shouldSelectViewController:viewController]){
            return;
        }
    }
    self.selectedIndex = selectedIndex;
    if(self.delegate&&[self.delegate respondsToSelector:@selector(customTabBarController:didSelectViewController:)]){
        [self.delegate customTabBarController:self didSelectViewController:viewController];
    }
}
@end

@implementation UIViewController (MKUICustomTabBarController)
- (MKUICustomTabBarController *)mk_customTabBarController{
    return (MKUICustomTabBarController *)[self mk_viewControllerOfFirstWithClass:MKUICustomTabBarController.class];
}
@end
